package org.concept.box.analyzer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.concept.box.grid.BoxGrid;
import org.concept.box.grid.TurnException;
import org.concept.box.result.BoxAction;

public class ExhaustionAnalyzer implements Analyzer {
	private Iterator<BoxAction> loop(BoxGrid grid) {
		List<BoxAction> gridList = new ArrayList<BoxAction>();
		if (grid.allowTurnDown())
			gridList.add(BoxAction.TURNUP);
		if (grid.allowTurnUp())
			gridList.add(BoxAction.TURNDOWN);
		if (grid.allowTurnLeft())
			gridList.add(BoxAction.TURNRIGHT);
		if (grid.allowTurnRight())
			gridList.add(BoxAction.TURNLEFT);
		return gridList.iterator();
	}

	public BoxGrid turn(BoxGrid grid, BoxAction action) {
		if (action.equals(BoxAction.TURNUP))
			return grid.turnDown();
		if (action.equals(BoxAction.TURNDOWN))
			return grid.turnUp();
		if (action.equals(BoxAction.TURNRIGHT))
			return grid.turnLeft();
		if (action.equals(BoxAction.TURNLEFT))
			return grid.turnRight();
		return null;
	}

	private void loopAnalyzer(BoxGrid grid, List<BoxAction> actionList,
			List<BoxAction[]> iterList, int level, int maxLevel) {
		if (grid.isSorted()) {
			BoxAction[] arr = actionList.subList(0, level).toArray(
					new BoxAction[level]);
			iterList.add(arr);
			return;
		}
		if (level == maxLevel)
			return;
		Iterator<BoxAction> iter = loop(grid);
		while (iter.hasNext()) {
			BoxAction a = iter.next();
			if (level > 0 && a.isOpposite(actionList.get(level - 1)))
				continue;
			BoxGrid o = turn(grid, a);
			if (actionList.size() > level)
				actionList.set(level, a);
			else
				actionList.add(a);
			loopAnalyzer(o, actionList, iterList, level + 1, maxLevel);
		}

	}

	public Iterator<BoxAction> analyze(BoxGrid grid) {
		List<BoxAction> actionList = new ArrayList<BoxAction>();
		List<BoxAction[]> listItem = new ArrayList<BoxAction[]>();
		if (grid.isNotSorted()) {
			loopAnalyzer(grid, actionList, listItem, 0, 25);
		}else{
			throw new TurnException("is sorted!!");
		}
		if (listItem.size() > 0)
			return Arrays.asList(listItem.get(0)).iterator();
		throw new TurnException("cant't turn over!!");
	}

	public static void main(String[] args) {
		BoxGrid g = BoxGrid.asString("138a652a704", "a");
		System.out.println(g);
		Analyzer analyzer = new ExhaustionAnalyzer();
		Iterator<BoxAction> iter = analyzer.analyze(g);
		while (iter.hasNext()) {
			System.out.println(iter.next());
		}
	}
}
